#include "StdAfx.h"
#include "SymbolTable.h"

SymbolTable::SymbolTable()
{
	size=0;
	staticCount=0;
	fieldCount=0;
	argCount=0;
	varCount=0;
}

void SymbolTable::startnewSubroutine()
{
	size=0;
	staticCount=0;
	fieldCount=0;
	argCount=0;
	varCount=0;
}

bool SymbolTable::searchSymbol( string name )
{
	for(int i=0;i<size;i++)
	{
		if(symTab[i].name==name) 
			return true;
	}
	return false;
}

void SymbolTable::writePushPop( string name, fstream& stream, bool isPush )
{
	for(int i=0;i<size;i++)
		if(symTab[i].name==name)
		{
			// are we pushing or popping?
			isPush ? stream << "push " : stream << "pop ";
			if(symTab[i].kind=="static")
			{
				stream << "static ";
			}
			else if(symTab[i].kind=="field")
			{
				stream << "this ";
			}
			else if(symTab[i].kind=="arg")
			{
				stream << "argument ";
			}
			else if(symTab[i].kind=="var") 
			{
				stream << "local ";
			}

			stream << symTab[i].index << endl;
			return;
		}
}

std::string SymbolTable::typeOf( string name )
{
	for(int i=0;i<size;i++)
	{
		if(symTab[i].name==name) 
			return symTab[i].type;
	}
	return "";
}

void SymbolTable::define(string name, string type, string kind)
{
	if(searchSymbol(name))
	{
		cout << "Duplication of variable " << name << endl;
		exit(0);
	}
	symTab[size].name=name;
	symTab[size].type=type;
	symTab[size].kind=kind;
	if(kind=="static") 
	{
		symTab[size].index=staticCount++;
	}
	else if(kind=="field") 
	{
		symTab[size].index=fieldCount++;
	}
	else if(kind=="arg") 
	{
		symTab[size].index=argCount++;
	}
	else if(kind=="var") 
	{
		symTab[size].index=varCount++;
	}
	else
	{ 
		cout << "Invalid variable kind\n"; exit(0);
	}
	size++;
}
